package com.kang.c0c.symbol;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;

import com.kang.c0c.util.Context;

/**
 * 输出语法分析器生成的符号表
 *
 * @author kang
 *
 * Feb 8, 2009
 */
public class SymbolScanner {
	private Vector<NameTable> stack;
	private Vector<String> functions;
	private PrintWriter out;
	
	public SymbolScanner(Context context, String outFile){
		GlobalTable globalTable = GlobalTable.instance(context);
		stack = new Vector<NameTable>();
		functions = new Vector<String>();
		stack.add(globalTable.nameTable);
		functions.add("Global");
		
		try{
			File file = new File("src/com/kang/c0c/out/" + outFile);
			
			if(file.exists() && !file.isDirectory()){
				out = new PrintWriter(file);
			}else if(! file.exists()){
				if(!file.createNewFile())
					System.err.println("Cann't create the new file " + file.getAbsolutePath());
				else
					out = new PrintWriter(file);
			}else{
				System.err.println("The output file is a directory!");
			}
		}catch(IOException ex){
			ex.printStackTrace();
		}
	}
	
	public void showSymbolTable() throws IOException{
		out.println("Symbol Table>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
		out.println();
		out.printf("%10s%10s%8s%8s\n", "Name", "Kind", "Type", "Value");
		while(stack.size() > 0)
			showNameTable(stack.elementAt(0));
		out.close();
		
	}
	
	private void print(String arg1, String arg2, String arg3, String arg4){
		if(arg1 == null)
			arg1 = "";
		if(arg2 == null)
			arg2 = "";
		if(arg3 == null)
			arg3 = "";
		if(arg4 == null)
			arg4 = "";
		
		out.printf("%10s%10s%8s%8s\n", arg1, arg2, arg3, arg4);
	}
	
	public void showNameTable(NameTable table) throws IOException{
		out.println((functions.elementAt(0) + "\t:----------------------------------"));
		
		for(int i=0;i<table.size();i++){
			Symbol sym = table.symbolAt(i);
			
			if(Symbol.isVar(sym)){
				print(sym.getName(), "VARIABLE", null, null);
			}else if(Symbol.isConstant(sym)){
				ConstantSymbol conSym = (ConstantSymbol)sym;
				print(sym.getName(), "CONSTANT", null, "" + conSym.getValue());
			}else if(Symbol.isFunc(sym)){
				FunctionSymbol funcSym = (FunctionSymbol)sym;
				
				if(FunctionSymbol.isInt(funcSym))
					print(funcSym.getName(), "FUNCTION", "INT", null);
				else
					print(funcSym.getName(), "FUNCTION", "VOID", null);
				
				stack.add(funcSym.nameTable);
				functions.add(funcSym.getName());
			}else if(Symbol.isParam(sym)){
				print(sym.getName(), "PARAMETER", null, null);
			}
		}
		
		stack.remove(0);
		functions.remove(0);
	}
}
